package com.smy.baseutil.date;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.TimeZone;
import java.util.regex.Pattern;

/**   
  * @Description: 日期帮助类
  * @author zhoutao
  * @date 2018年1月2日 下午3:55:34 
  * @version V1.0   
  */
public class DateTimeUtils {

    public static final  long             SECOND                = 1000L;
    public static final  long             MINUTE                = 60000L;
    public static final  long             HOUR                  = 3600000L;
    public static final  long             DAY                   = 86400000L;
    public static final  long             WEEK                  = 604800000L;
    public static final  String           DATE_FORMAT           = "yyyy-MM-dd";
    public static final  String           DATETIME_FORMAT       = "yyyy-MM-dd HH:mm:ss";
    public static final  String           DATETIME_FORMAT2      = "yyyyMMdd";
    public static final  String           DATETIME_FORMAT3      = "yyyyMMddHHmmss";
    public static final  String           DATETIME_FORMAT4      = "HHmmss";
    public static final  String           DATETIME_LONG_FORMAT  = "yyyy-MM-dd HH:mm:ss.SSS";
    public static final  String           DATE_FORMAT_CHINESE   = "yyyy年MM月dd日";
    public static final  String           YEAR_MONTH_DAY_FORMAT = "yyyyMMdd";
    public static final  String           YEAR_MONTH_FORMAT     = "yyyyMM";
    public static final  String           YEAR_FORMAT           = "yyyy";
    public static final  String           MONTH_DAY_FORMAT      = "MMdd";
    public static final  String           MONTH_FORMAT          = "MM";
    public static final  String           DAY_FORMAT            = "dd";
    public static final  int[]            dayArray              = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    private static final SimpleDateFormat shortSdf              = new SimpleDateFormat("yyyy-MM-dd");
    private static final SimpleDateFormat longSdf               = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private static final int              FIRST_DAY             = Calendar.MONDAY;

    public static Date date(int y, int m, int d) {
        return date(y, m - 1, d, 0, 0, 0);
    }

    public static Date date(int y, int m, int d, int h, int ms, int s) {
        Calendar cal = Calendar.getInstance();
        cal.set(y, m, d, h, ms, s);
        return cal.getTime();
    }

    public static Date removeTime(Date d) {
        return setTime(d, 0, 0, 0);
    }

    public static Date setTime(Date d, int h, int m, int s) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(d);
        cal.set(11, h);
        cal.set(12, m);
        cal.set(13, s);
        cal.set(14, 0);
        return cal.getTime();
    }

    public static String formatDate(String format, Date d) {
        if (d == null) {
            return null;
        }
        return new SimpleDateFormat(format).format(d);
    }

    public static String formatNow() {
        return new SimpleDateFormat("yyyyMMdd").format(getNowDateByServer());
    }

    public static String formatDate(Date d) {
        if (d == null) {
            return null;
        }
        return new SimpleDateFormat("yyyy-MM-dd").format(d);
    }

    public static String formatDateTimeStr(String d) {
        if (d == null || "".equals(d)) {
            return null;
        }
        return d.substring(0, 10);
    }

    public static String formatDateTime(Date d) {
        if (d == null) {
            return null;
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(d);
    }

    public static String formatShortDateTime(Date d) {
        if (d == null) {
            return null;
        }
        return new SimpleDateFormat("yyyy-MM-dd HH:mm").format(d);
    }

    public static String formatDateTimeStr(Date d) {
        if (d == null) {
            return null;
        }
        return new SimpleDateFormat("yyyyMMddHHmmss").format(d);
    }

    public static String formatDateTimeLongStr(Date d) {
        if (d == null) {
            return null;
        }
        return new SimpleDateFormat("yyyyMMddHHmmssSSS").format(d);
    }

    public static String formatDateTimeCnStr(Date d) {
        if (d == null) {
            return null;
        }
        return new SimpleDateFormat(DATE_FORMAT_CHINESE).format(d);
    }

    public static String formatPeriod(long period) {
        StringBuffer buf = new StringBuffer(20);

        long r = period;
        long d = r / 86400000L;
        r %= 86400000L;
        if (d != 0L) {
            buf.append(d).append("d");
        }
        d = r / 3600000L;
        r %= 3600000L;
        if (d != 0L) {
            buf.append(d).append("h");
        }
        d = r / 60000L;
        r %= 60000L;
        if (d != 0L) {
            buf.append(d).append("m");
        }
        d = r / 1000L;
        r %= 1000L;
        if ((d != 0L) || (r != 0L)) {
            buf.append(d);
            if (r != 0L) {
                buf.append(".").append(r);
            }
            buf.append("s");
        }
        return buf.toString();
    }

    public static Date parse(String v, String fm, Date def) {
        if ((v == null) || (v.trim().length() == 0))
            return def;
        try {
            return new SimpleDateFormat(fm).parse(v);
        } catch (Exception e) {
        }
        return def;
    }

    public static Date parseDate(String v, Date def) {
        return parse(v, "yyyy-MM-dd", def);
    }

    public static Date parseLongDateTime(String v, Date def) {
        return parse(v, "yyyy-MM-dd HH:mm:ss.SSS", def);
    }

    public static Date parseLongDateTime(String v, long def) {
        return parse(v, "yyyy-MM-dd HH:mm:ss.SSS", new Date(def));
    }

    public static long parseDate(String v, long def) {
        Date r = parse(v, "yyyy-MM-dd", new Date(def));
        return r.getTime();
    }

    public static Date parseDateTime(String v, Date def) {
        return parse(v, "yyyy-MM-dd HH:mm:ss", def);
    }

    public static long parseDateTime(String v, long def) {
        Date r = parse(v, "yyyy-MM-dd HH:mm:ss", new Date(def));
        return r.getTime();
    }

    public static Date getFirstDayOfWeek(Date date) {
        return getFirstDayOfWeek(date, 1);
    }

    public static Date getFirstDayOfWeek(Date date, int firstDayOfWeek) {
        Calendar cal = Calendar.getInstance();
        if (date != null)
            cal.setTime(date);
        cal.setFirstDayOfWeek(firstDayOfWeek);
        cal.set(7, firstDayOfWeek);
        cal.set(11, 0);
        cal.set(12, 0);
        cal.set(13, 0);
        cal.set(14, 0);
        return cal.getTime();
    }

    public static Date getLastDayOfWeek(Date date) {
        return getLastDayOfWeek(date, 1);
    }

    public static Date getLastDayOfWeek(Date date, int firstDayOfWeek) {
        Calendar cal = Calendar.getInstance();
        if (date != null)
            cal.setTime(date);
        cal.setFirstDayOfWeek(firstDayOfWeek);
        cal.set(7, firstDayOfWeek);
        cal.add(7, 6);
        cal.set(11, 0);
        cal.set(12, 0);
        cal.set(13, 0);
        cal.set(14, 0);
        return cal.getTime();
    }

    public static Date getFirstDayOfMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        if (date != null)
            cal.setTime(date);
        cal.set(5, 1);
        cal.set(11, 0);
        cal.set(12, 0);
        cal.set(13, 0);
        cal.set(14, 0);
        return cal.getTime();
    }

    public static Date getLastDayOfMonthThisYear(Date date) {
        Calendar cal = Calendar.getInstance();
        if (date != null)
            cal.setTime(date);
        cal.set(5, cal.getActualMaximum(5));
        cal.set(11, 0);
        cal.set(12, 0);
        cal.set(13, 0);
        cal.set(14, 0);
        return cal.getTime();
    }

    public static boolean isDateTimeFormat(String date) {
        if (date == null) {
            return false;
        }

        if (date.trim().replaceAll("\\s+", " ").length() > "yyyy-MM-dd HH:mm:ss".length()) {
            return false;
        }

        if (!Pattern
                .matches("[12]{1}[09]{1}\\d{2}-[01]?[0-9]?-[0-3]?[0-9]?\\s+[0-5]?[0-9]?:[0-5]?[0-9]?:[0-5]?[0-9]?",
                        date)) {
            return false;
        }
        return true;
    }

    public static boolean isRightDate(String date, String format) {
        if ((date == null) || (format == null)) {
            return false;
        }
        try {
            new SimpleDateFormat(format).parse(date);
        } catch (ParseException e) {
            return false;
        }
        return true;
    }

    public static String formatDate(Date date, String pattern) {
        return new SimpleDateFormat(pattern).format(date);
    }

    public static String formatLongDateTime(Date date) {
        return formatDate(date, "yyyy-MM-dd HH:mm:ss.SSS");
    }

    public static String formatLongDateTime(Long time) {
        if (time == null || time == 0L) {
            return null;
        }
        return formatDate(new Date(time), "yyyy-MM-dd HH:mm:ss.SSS");
    }

    public static boolean isLeapYear(int year) {
        if (year % 400 == 0)
            return true;
        if (year % 4 == 0) {
            if (year % 100 == 0) {
                return false;
            }
            return true;
        }
        return false;
    }

    public static Date getLastDayOfMonth(Date date) {
        Calendar gc = Calendar.getInstance();
        gc.setTime(date);
        gc.add(2, 1);
        gc.add(5, -1 * gc.get(5));

        gc.set(10, 23);
        gc.set(12, 59);
        gc.set(13, 59);
        return new Date(gc.getTimeInMillis());
    }

    public static Date getStartDateByDate(Date date) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        gc.set(10, 0);
        gc.set(12, 0);
        gc.set(13, 0);
        return new Date(gc.getTimeInMillis());
    }

    public static Date getEndDateByDate(Date date) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(date);
        gc.set(10, 23);
        gc.set(12, 59);
        gc.set(13, 59);
        return new Date(gc.getTimeInMillis());
    }

    public static synchronized Date getDateTime(int year, int month, int day) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        if ((isLeapYear(year)) && (month == 1)) {
            day++;
        }
        gc.set(year, month, day);
        return new Date(gc.getTimeInMillis());
    }

    public static Date getNowDateByServer() {
        return new Date(System.currentTimeMillis());
    }

    public static Integer getNowYearByServer() {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(getNowDateByServer());
        return Integer.valueOf(gc.get(1));
    }

    public static Integer getNowMonthByServer() {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(getNowDateByServer());
        return Integer.valueOf(gc.get(2));
    }

    public static Integer getNowDayByServer() {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(getNowDateByServer());
        return Integer.valueOf(gc.get(8));
    }

    public static String formatDateToString(Date tm) {
        if (tm == null) {
            return "";
        }
        return formatDate(tm, "yyyy-MM-dd");
    }

    public static String formatDateToString(String date_format) {
        return formatDate(getNowDateByServer(), date_format);
    }

    public static String formatDateToString(Date tm, String date_format) {
        if (tm == null) {
            return "";
        }
        return formatDate(tm, date_format);
    }

    public static String getLastMonth(String sMonth) {
        int iYear = Integer.parseInt(sMonth.substring(0, 4));
        int iMonth = Integer.parseInt(sMonth.substring(4, 6));
        if (iMonth == 1) {
            iYear--;
            iMonth = 12;
        } else {
            iMonth--;
        }
        String sTmpYear = "0000" + Integer.toString(iYear);
        String sTmpMonth = "00" + Integer.toString(iMonth);
        return sTmpYear.substring(sTmpYear.length() - 4, sTmpYear.length())
               + sTmpMonth.substring(sTmpMonth.length() - 2, sTmpMonth.length());
    }

    public static String getNextMonth(String sMonth) {
        int iYear = Integer.parseInt(sMonth.substring(0, 4));
        int iMonth = Integer.parseInt(sMonth.substring(4, 6));
        if (iMonth == 12) {
            iYear++;
            iMonth = 1;
        } else {
            iMonth++;
        }
        String sTmpYear = "0000" + Integer.toString(iYear);
        String sTmpMonth = "00" + Integer.toString(iMonth);
        return sTmpYear.substring(sTmpYear.length() - 4) + sTmpMonth.substring(sTmpMonth.length() - 2);
    }

    public static String getRelativeMonth(String sMonth, int shiftValue) {
        int tempMonth = Integer.parseInt(sMonth.substring(0, 4)) * 12 + Integer.parseInt(sMonth.substring(4, 6));
        tempMonth += shiftValue;
        if (tempMonth % 12 == 0) {
            return tempMonth / 12 - 1 + "12";
        }
        String sTmpMonth = "00" + tempMonth % 12;
        return tempMonth / 12 + sTmpMonth.substring(sTmpMonth.length() - 2);
    }

    public static int calcuMonth(String begMonth, String endMonth) {
        int result = 0;

        if ((begMonth == null) || (begMonth.length() != 6) || (endMonth == null) || (endMonth.length() != 6)) {
            return result;
        }
        result = 12 * (Integer.parseInt(endMonth.substring(0, 4)) - Integer.parseInt(begMonth.substring(0, 4)))
                 + Integer.parseInt(endMonth.substring(4)) - Integer.parseInt(begMonth.substring(4));
        return result;
    }

    public static String getYearFirstAcctTermNoByDate(Date dateTime) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(dateTime);
        return gc.get(1) + "00";
    }

    public static Date getFirstDateForYear(Date dateTime) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(dateTime);
        return null;
    }

    public static int getYearByDate(Date dateTime) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(dateTime);
        return gc.get(1);
    }

    public static int getMonthByDate(Date dateTime) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(dateTime);
        return gc.get(2) + 1;
    }

    public static int getDayByDate(Date dateTime) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(dateTime);
        return gc.get(5);
    }

    public static Date getNextDay(Date dateTime) {
        Calendar gc = Calendar.getInstance();
        gc.setTime(dateTime);
        gc.add(5, 1);
        return gc.getTime();
    }

    public static String createAcctTermNoByDate(Date time) {
        String acctTermNo = "";
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(time);
        acctTermNo = acctTermNo + gc.get(1);
        acctTermNo = acctTermNo
                     + (gc.get(2) >= 9 ? Integer.valueOf(gc.get(2) + 1) : new StringBuilder("0").append(gc.get(2) + 1)
                .toString());
        return acctTermNo;
    }

    public static String getYearMonth(Date time) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(time);
        return String.valueOf(cal.get(1))
               + (cal.get(2) >= 9 ? String.valueOf(cal.get(2) + 1) : new StringBuilder("0").append(
                String.valueOf(cal.get(2) + 1)).toString());
    }

    public static Date conversionDate(int year, int month) {
        Calendar c = Calendar.getInstance();
        c.set(year, month, 0);
        return c.getTime();
    }

    public static Date getFirstDayOfMonthByAcctTermNo(String AcctTermNo) {
        int year = Integer.parseInt(AcctTermNo.substring(0, 4));
        int month = Integer.parseInt(AcctTermNo.substring(4, 6));
        return date(year, month, 1);
    }

    public static boolean compareDate(Date startDate, Date endDate) {
        if (endDate.after(startDate)) {
            return true;
        }
        return false;
    }

    public static List<Date> getBetweenDates(Date startDate, Date endDate) {
        if (startDate == null) {
            if (endDate != null) {
                return Arrays.asList(new Date[] { endDate });
            }
        } else if (endDate == null) {
            return Arrays.asList(new Date[] { startDate });
        }

        List<Date> dates = new ArrayList<Date>();
        if (startDate.getTime() > endDate.getTime()) {
            return dates;
        }

        Calendar startCal = Calendar.getInstance();
        startCal.setTime(startDate);
        Calendar endCal = Calendar.getInstance();
        endCal.setTime(endDate);

        int startYear = 0;
        int startMonth = 0;
        int endYear = endCal.get(1);
        int endMonth = endCal.get(2);
        while (true) {
            dates.add(new Date(startCal.getTime().getTime()));
            startYear = startCal.get(1);
            startMonth = startCal.get(2);

            if ((startYear == endYear) && (startMonth == endMonth)) {
                break;
            }
            startCal.add(2, 1);
        }
        return dates;
    }

    public static List<String> getBetweenDates(Date startDate, Date endDate, String dateFormat) {
        List<String> lst = new ArrayList<String>();
        List<Date> listDate = getBetweenDates(startDate, endDate);
        if (listDate != null && listDate.size() > 0) {
            for (Date d : listDate) {
                lst.add(formatDate(d, dateFormat));
            }
        }
        return lst;
    }

    public static String getUpAcctTermNoForDate(Date time, int months) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(time);
        cal.add(2, months);
        cal.set(10, 0);
        cal.set(12, 0);
        cal.set(13, 0);
        return createAcctTermNoByDate(cal.getTime());
    }

    public static Date getFirstYearDay(Date dateTime) {
        GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
        gc.setTime(dateTime);
        gc.get(1);
        gc.set(gc.get(1), 0, 1);
        return gc.getTime();
    }

    public static Date genNewDateTime(Date oriDateTime, int type, int rolls) {
        GregorianCalendar c1 = new GregorianCalendar();
        c1.setTime(oriDateTime);
        c1.add(type, rolls);
        return c1.getTime();
    }

    @SuppressWarnings("deprecation")
    public static String getYearMonthToYYYYMM(Date date) {
        String yearMonth = "";
        if (date.getMonth() + 1 < 10)
            yearMonth = date.getYear() + 1900 + "0" + (date.getMonth() + 1);
        else {
            yearMonth = date.getYear() + 1900 + (date.getMonth() + 1) + "";
        }
        return yearMonth;
    }

    public static String getPreMonthYYYYMM(String yyyymm) {
        String str = yyyymm.substring(0, 4) + "-" + yyyymm.substring(4, 6) + "-01";
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date date = new Date(df.parse(str).getTime());
            return getYearMonthToYYYYMM(genNewDateTime(date, 2, -1));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String StringYearMonthByAcctTermNo(String accTermNO, int month) {
        String str = accTermNO.substring(0, 4) + "-" + accTermNO.substring(4, 6) + "-01";
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date date = new Date(df.parse(str).getTime());
            return getYearMonthToYYYYMM(genNewDateTime(date, 2, month));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static int getBetweenDays(Date startDate, Date endDate) {
        return Math.abs(new Long((removeTime(startDate).getTime() - removeTime(endDate).getTime()) / 86400000L)
                .intValue());
    }

    public static Date getStartMonthDate(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month - 1, 1);
        return calendar.getTime();
    }

    public static Date getEndMonthDate(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, month - 1, 1);
        int day = calendar.getActualMaximum(5);
        calendar.set(year, month - 1, day);
        return calendar.getTime();
    }

    public static Date getEndMonthDate(String yearmonth) {
        int year = Integer.parseInt(yearmonth.substring(0, 4));
        int month = Integer.parseInt(yearmonth.substring(4, 6));
        return getEndMonthDate(year, month);
    }

    public static long betweenMonths(Date endDate, Date startDate) {
        Calendar cal = Calendar.getInstance();
        cal.clear();
        cal.setTime(endDate);
        long endmonths = cal.get(1) * 12 + cal.get(2);
        cal.setTime(startDate);
        long startmonths = cal.get(1) * 12 + cal.get(2);
        return endmonths - startmonths;
    }

    public static long betweenDate(Date enddate, Date startdate, String flag) {
        if ("Y".equalsIgnoreCase(flag))
            return Math.abs(getYearByDate(enddate) - getYearByDate(startdate));
        if ("M".equalsIgnoreCase(flag))
            return betweenMonths(enddate, startdate);
        if ("D".equalsIgnoreCase(flag)) {
            return getBetweenDays(startdate, enddate);
        }
        return 0L;
    }

    public static long betweenMinute(Date enddate, Date startdate) {
        long mins = 60L * 1000L;
        long dayNumber = (enddate.getTime() - startdate.getTime()) / mins;
        return dayNumber;
    }

    public static Date add(Date source, int field, int amount) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(source);
        cal.add(field, amount);
        return cal.getTime();
    }

    public static Date addSeconds(Date source, int seconds) {
        return add(source, 13, seconds);
    }

    public static Date addMinutes(Date source, int minutes) {
        return add(source, 12, minutes);
    }

    public static Date addHours(Date source, int hours) {
        return add(source, 11, hours);
    }

    public static Date addDays(Date source, int day) {
        return add(source, 5, day);
    }

    public static Date addMonths(Date source, int months) {
        return add(source, 2, months);
    }

    public static Date addYears(Date source, int years) {
        return add(source, 1, years);
    }

    public static String getCurrentLastAcctTerm(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return String.valueOf(cal.get(1)) + "12";
    }

    public static String getPreviousLastAcctTerm(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return String.valueOf(cal.get(1) - 1) + "12";
    }

    public static Date max(Date[] dates) {
        if (((dates == null ? 1 : 0) | (dates.length == 0 ? 1 : 0)) != 0) {
            return null;
        }
        if (dates.length == 1) {
            return dates[0];
        }
        Date maxDate = dates[0];
        Date[] arrayOfDate = dates;
        int j = dates.length;
        for (int i = 0; i < j; i++) {
            Date d = arrayOfDate[i];
            if (d != null) {
                if (maxDate == null) {
                    maxDate = d;
                }
                if (maxDate != null) {
                    if (maxDate.compareTo(d) < 0)
                        maxDate = d;
                }
            }
        }
        return maxDate;
    }

    public static Date getGMTDate() {
        Date d = new Date();
        return new Date(d.getTime() - TimeZone.getDefault().getOffset(System.currentTimeMillis()));
    }

    public static Date getGMTDate(long date) {
        Date d = new Date(date);
        return new Date(d.getTime() - TimeZone.getDefault().getOffset(System.currentTimeMillis()));
    }

    public static Date getGMTPlus800Date(long date) {
        Date d = new Date(date);
        return new Date(d.getTime() - TimeZone.getDefault().getOffset(System.currentTimeMillis()) + 28800000L);
    }

    public static Date getGMTPlus800Date() {
        return getGMTPlus800Date(new Date().getTime());
    }

    @SuppressWarnings("deprecation")
    public static boolean isSameDay(Date d1, Date d2) {
        if ((d1 == null) || (d2 == null)) {
            return false;
        }
        if ((d1.getYear() == d2.getYear()) && (d1.getMonth() == d2.getMonth()) && (d1.getDate() == d2.getDate())) {
            return true;
        }

        return false;
    }

    @SuppressWarnings("deprecation")
    public static boolean isSameMonth(Date d1, Date d2) {
        if ((d1 == null) || (d2 == null)) {
            return false;
        }
        if ((d1.getYear() == d2.getYear()) && (d1.getMonth() == d2.getMonth())) {
            return true;
        }
        return false;
    }

    /**
     * 判断是否为日期
     *
     * @param str
     * @return
     * @author TONY
     * @date:Feb 26, 2016 5:13:50 PM
     */
    public static boolean isValidDate(String str) {
        boolean convertSuccess = true;
        SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
        try {
            format.setLenient(false);
            format.parse(str);
        } catch (ParseException e) {
            convertSuccess = false;
        }
        return convertSuccess;
    }

    /**
     * 返回当月最后一天的日期
     */
    public static Date getLastDayOfMonthByDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DATE, calendar.getMaximum(Calendar.DATE));
        return calendar.getTime();
    }

    /**
     * 计算两个日期相差月数
     *
     * @param date1
     * @param date2
     * @return
     * @throws ParseException
     * @author slj
     * @date:Mar 11, 2016 9:23:13 AM
     */
    public static int getMonthSpace(String date1, String date2) {

        int result = 0;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        try {
            c1.setTime(sdf.parse(date1));
            c2.setTime(sdf.parse(date2));
            result = c2.get(Calendar.MONDAY) - c1.get(Calendar.MONTH);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return result == 0 ? 1 : Math.abs(result);
    }

    /**
     * 计算两个日期相差月数
     *
     * @param date1
     * @param date2
     * @return
     * @throws Exception
     * @author slj
     * @date:Mar 11, 2016 9:23:13 AM
     */
    public static int getMonthSpaceByDate(Date date1, Date date2) {

        int result = 0;
        Calendar c1 = Calendar.getInstance();
        Calendar c2 = Calendar.getInstance();
        try {
            c1.setTime(date1);
            c2.setTime(date2);
            result = c2.get(Calendar.MONDAY) - c1.get(Calendar.MONTH);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return result == 0 ? 1 : Math.abs(result);
    }

    /**
     * 当月的开始时间，即2012-03-1
     *
     * @return
     */
    public static Date getMonthStartTime(Calendar c) {
        Date now = null;
        try {
            c.add(Calendar.MONTH, 0);
            c.set(Calendar.DAY_OF_MONTH, 1);//设置为1号,当前日期既为本月第一天
            now = longSdf.parse(shortSdf.format(c.getTime()) + " 00:00:00");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 当月的结束时间，即2012-03-31 23:59:59
     *
     * @return
     */
    public static Date getMonthEndTime(Calendar c) {
        //Calendar c = Calendar.getInstance();
        int currentMonth = c.get(Calendar.MONTH) + 1;
        Date now = null;
        try {
            if (currentMonth == 1) {
                c.set(Calendar.MONTH, 0);
                c.set(Calendar.DATE, 31);
            } else if (currentMonth == 2) {
                c.set(Calendar.MONTH, 1);
                int date = 28;
                if (isLeapYear(Calendar.YEAR)) {
                    date = 29;
                }
                c.set(Calendar.DATE, date);
            } else if (currentMonth == 3) {
                c.set(Calendar.MONTH, 2);
                c.set(Calendar.DATE, 31);
            } else if (currentMonth == 4) {
                c.set(Calendar.MONTH, 3);
                c.set(Calendar.DATE, 30);
            } else if (currentMonth == 5) {
                c.set(Calendar.MONTH, 4);
                c.set(Calendar.DATE, 31);
            } else if (currentMonth == 6) {
                c.set(Calendar.MONTH, 5);
                c.set(Calendar.DATE, 30);
            } else if (currentMonth == 7) {
                c.set(Calendar.MONTH, 6);
                c.set(Calendar.DATE, 31);
            } else if (currentMonth == 8) {
                c.set(Calendar.MONTH, 7);
                c.set(Calendar.DATE, 31);
            } else if (currentMonth == 9) {
                c.set(Calendar.MONTH, 8);
                c.set(Calendar.DATE, 30);
            } else if (currentMonth == 10) {
                c.set(Calendar.MONTH, 9);
                c.set(Calendar.DATE, 31);
            } else if (currentMonth == 11) {
                c.set(Calendar.MONTH, 10);
                c.set(Calendar.DATE, 30);
            } else if (currentMonth == 12) {
                c.set(Calendar.MONTH, 11);
                c.set(Calendar.DATE, 31);
            }
            now = longSdf.parse(shortSdf.format(c.getTime()) + " 23:59:59");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 双月的开始时间，即2012-01-1 00:00:00
     *
     * @return
     */
    public static Date getCurrentDoubleMonthStartTime(Calendar c) {
        //Calendar c = Calendar.getInstance();
        int currentMonth = c.get(Calendar.MONTH) + 1;
        Date now = null;
        try {
            if (currentMonth >= 1 && currentMonth <= 2)
                c.set(Calendar.MONTH, 0);
            else if (currentMonth >= 3 && currentMonth <= 4)
                c.set(Calendar.MONTH, 2);
            else if (currentMonth >= 5 && currentMonth <= 6)
                c.set(Calendar.MONTH, 4);
            else if (currentMonth >= 7 && currentMonth <= 8)
                c.set(Calendar.MONTH, 6);
            else if (currentMonth >= 9 && currentMonth <= 10)
                c.set(Calendar.MONTH, 8);
            else if (currentMonth >= 11 && currentMonth <= 12)
                c.set(Calendar.MONTH, 10);
            c.set(Calendar.DATE, 1);
            now = longSdf.parse(shortSdf.format(c.getTime()) + " 00:00:00");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 双月的结束时间，即2012-03-31 23:59:59
     *
     * @return
     */
    public static Date getCurrentDoubleMonthEndTime(Calendar c) {
        //Calendar c = Calendar.getInstance();
        int currentMonth = c.get(Calendar.MONTH) + 1;
        Date now = null;
        try {
            if (currentMonth >= 1 && currentMonth <= 2) {
                c.set(Calendar.MONTH, 1);
                int date = 28;
                if (isLeapYear(Calendar.YEAR)) {
                    date = 29;
                }
                c.set(Calendar.DATE, date);
            } else if (currentMonth >= 3 && currentMonth <= 4) {
                c.set(Calendar.MONTH, 3);
                c.set(Calendar.DATE, 30);
            } else if (currentMonth >= 5 && currentMonth <= 6) {
                c.set(Calendar.MONTH, 5);
                c.set(Calendar.DATE, 30);
            } else if (currentMonth >= 7 && currentMonth <= 8) {
                c.set(Calendar.MONTH, 7);
                c.set(Calendar.DATE, 31);
            } else if (currentMonth >= 9 && currentMonth <= 10) {
                c.set(Calendar.MONTH, 9);
                c.set(Calendar.DATE, 31);
            } else if (currentMonth >= 11 && currentMonth <= 12) {
                c.set(Calendar.MONTH, 11);
                c.set(Calendar.DATE, 31);
            }
            now = longSdf.parse(shortSdf.format(c.getTime()) + " 23:59:59");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 当前季度的开始时间，即2012-01-1 00:00:00
     *
     * @return
     */
    public static Date getCurrentQuarterStartTime(Calendar c) {
        //Calendar c = Calendar.getInstance();
        int currentMonth = c.get(Calendar.MONTH) + 1;
        Date now = null;
        try {
            if (currentMonth >= 1 && currentMonth <= 3)
                c.set(Calendar.MONTH, 0);
            else if (currentMonth >= 4 && currentMonth <= 6)
                c.set(Calendar.MONTH, 3);
            else if (currentMonth >= 7 && currentMonth <= 9)
                c.set(Calendar.MONTH, 4);
            else if (currentMonth >= 10 && currentMonth <= 12)
                c.set(Calendar.MONTH, 9);
            c.set(Calendar.DATE, 1);
            now = longSdf.parse(shortSdf.format(c.getTime()) + " 00:00:00");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 当前季度的结束时间，即2012-03-31 23:59:59
     *
     * @return
     */
    public static Date getCurrentQuarterEndTime(Calendar c) {
        //Calendar c = Calendar.getInstance();
        int currentMonth = c.get(Calendar.MONTH) + 1;
        Date now = null;
        try {
            if (currentMonth >= 1 && currentMonth <= 3) {
                c.set(Calendar.MONTH, 2);
                c.set(Calendar.DATE, 31);
            } else if (currentMonth >= 4 && currentMonth <= 6) {
                c.set(Calendar.MONTH, 5);
                c.set(Calendar.DATE, 30);
            } else if (currentMonth >= 7 && currentMonth <= 9) {
                c.set(Calendar.MONTH, 8);
                c.set(Calendar.DATE, 30);
            } else if (currentMonth >= 10 && currentMonth <= 12) {
                c.set(Calendar.MONTH, 11);
                c.set(Calendar.DATE, 31);
            }
            now = longSdf.parse(shortSdf.format(c.getTime()) + " 23:59:59");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 获取前/后半年的开始时间
     *
     * @return
     */
    public static Date getHalfYearStartTime(Calendar c) {
        //Calendar c = Calendar.getInstance();
        int currentMonth = c.get(Calendar.MONTH) + 1;
        Date now = null;
        try {
            if (currentMonth >= 1 && currentMonth <= 6) {
                c.set(Calendar.MONTH, 0);
            } else if (currentMonth >= 7 && currentMonth <= 12) {
                c.set(Calendar.MONTH, 6);
            }
            c.set(Calendar.DATE, 1);
            now = longSdf.parse(shortSdf.format(c.getTime()) + " 00:00:00");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;

    }

    /**
     * 获取前/后半年的结束时间
     *
     * @return
     */
    public static Date getHalfYearEndTime(Calendar c) {
        //Calendar c = Calendar.getInstance();
        int currentMonth = c.get(Calendar.MONTH) + 1;
        Date now = null;
        try {
            if (currentMonth >= 1 && currentMonth <= 6) {
                c.set(Calendar.MONTH, 5);
                c.set(Calendar.DATE, 30);
            } else if (currentMonth >= 7 && currentMonth <= 12) {
                c.set(Calendar.MONTH, 11);
                c.set(Calendar.DATE, 31);
            }
            now = longSdf.parse(shortSdf.format(c.getTime()) + " 23:59:59");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 获取某年最后一天日期
     *
     * @param year 年份
     * @return Date
     */
    public static Date getYearLast(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        calendar.roll(Calendar.DAY_OF_YEAR, -1);
        Date currYearLast = calendar.getTime();
        return currYearLast;
    }

    /**
     * 将字符串解析成日期类型，如果字符串含有/则按/分割,否则以-分
     *
     * @param 待解析的字符串
     * @return 解析后的日期
     * @since 0.1
     */
    public static Date getDate(String dateStr) {
        Date date = null;
        try {
            if (dateStr != null && !"".equals(dateStr)) {
                String separator = dateStr.indexOf('/') > 0 ? "/" : "-";
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy" + separator + "MM" + separator + "dd");
                date = simpleDateFormat.parse(dateStr);
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return date;
    }

    /**
     * 判断选择的日期是否是本周
     *
     * @param time
     * @return
     * @author LQY
     * @date:Mar 16, 2016 4:24:44 PM
     */
    public static boolean isThisWeek(long time) {
        Calendar calendar = Calendar.getInstance();
        int currentWeek = calendar.get(Calendar.WEEK_OF_YEAR);
        calendar.setTime(new Date(time));
        int paramWeek = calendar.get(Calendar.WEEK_OF_YEAR);
        if (paramWeek == currentWeek) {
            return true;
        }
        return false;
    }

    /**
     * 判断选择的日期是否是本周
     *
     * @param time
     * @return
     * @author LQY
     * @date:Mar 16, 2016 4:24:44 PM
     */
    public static boolean isNextWeek(long time) {
        Date now = new Date();
        int weekday = getWeekDay(now);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        for (int i = 0; i < 7; i++) {
            Calendar cal = Calendar.getInstance();
            cal.add(Calendar.DAY_OF_MONTH, +(8 - weekday + i));
            String nextDate = dateFormat.format(cal.getTime());
            try {
                if (time == dateFormat.parse(nextDate).getTime()) {
                    return true;
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return false;
    }

    /**
     * 获取下一周的第一天
     *
     * @param date
     * @return
     * @author LQY
     * @date:Mar 16, 2016 5:10:29 PM
     */
    public static Date getFirstDayNextWeek(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int week = cal.get(Calendar.DAY_OF_WEEK);
        if (week > 1) {
            cal.add(Calendar.DAY_OF_MONTH, -(week - 2) + 7);
        } else {
            cal.add(Calendar.DAY_OF_MONTH, 2 - week + 7);
        }
        return cal.getTime();
    }

    /**
     * 获得本周的第一天，即周日
     * lgh
     *
     * @return
     */
    public static Date getCurrentWeekDayStartTime() {
        Calendar c = Calendar.getInstance();
        try {
            int weekday = c.get(Calendar.DAY_OF_WEEK) - 1;
            c.add(Calendar.DATE, -weekday);
            c.setTime(longSdf.parse(shortSdf.format(c.getTime()) + " 00:00:00"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return c.getTime();
    }

    /**
     * 获得本周的最后一天，即本周六
     *
     * @return
     */
    public static Date getCurrentWeekDayEndTime() {
        Calendar c = Calendar.getInstance();
        try {
            int weekday = c.get(Calendar.DAY_OF_WEEK);
            c.add(Calendar.DATE, 7 - weekday);
            c.setTime(longSdf.parse(shortSdf.format(c.getTime()) + " 23:59:59"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return c.getTime();
    }

    /**
     * 获得本天的开始时间，即2012-01-01 00:00:00
     *
     * @return
     */
    public static Date getCurrentDayStartTime() {
        Date now = new Date();
        try {
            now = shortSdf.parse(shortSdf.format(now));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 获得本天的结束时间，即2012-01-01 23:59:59
     *
     * @return
     */
    public static Date getCurrentDayEndTime() {
        Date now = new Date();
        try {
            now = longSdf.parse(shortSdf.format(now) + " 23:59:59");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 获得本天的下一天开始时间，即2012-01-01 00:00:00
     *
     * @return
     */
    public static Date getNextNDayStartTime(int n) {
    	Date now = null;
        try {
        	Calendar calendar = Calendar.getInstance();
        	calendar.add(Calendar.DAY_OF_YEAR, n);
        	Date date = calendar.getTime();
            now = shortSdf.parse(shortSdf.format(date));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }
    
    /**
     * 获得本天的结束时间，即2012-01-01 23:59:59
     *
     * @return
     */
    public static Date getNextNDayEndTime(int n) {
        Date now = null;
        try {
        	Calendar calendar = Calendar.getInstance();
        	calendar.add(Calendar.DAY_OF_YEAR, n);
        	Date date = calendar.getTime();
            now = longSdf.parse(shortSdf.format(date) + " 23:59:59");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }
    
    /**
     * 获得本天的结束时间，即2012-01-01 23:59:59
     *
     * @return
     */
    public static Date getNextNYearDayEndTime(int year) {
        Date now = null;
        try {
        	Calendar calendar = Calendar.getInstance();
        	calendar.add(Calendar.YEAR, year);
        	Date date = calendar.getTime();
            now = longSdf.parse(shortSdf.format(date) + " 23:59:59");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }
    /**
     * 获取下一天的下一年日期
     * @param date
     * @param format
     * @return
     */
    public static String getDayOfNextYearDay(Date date, String format){
        String nextStr = "";
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH));
            calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR ) + 1);
            calendar.set(Calendar.HOUR_OF_DAY, 23);
            calendar.set(Calendar.MINUTE, 59);
            calendar.set(Calendar.SECOND, 59);
            nextStr = new SimpleDateFormat(format).format(calendar.getTime());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return nextStr;
    }
    
    public static void main(String[] args) {
    	System.out.println(DateTimeUtils.formatDateTime(getCurrentDayStartTime()));
    	System.out.println(DateTimeUtils.formatDateTime(getCurrentDayEndTime()));
    	
    	System.out.println(DateTimeUtils.formatDateTime(getNextNDayStartTime(100)));
    	System.out.println(DateTimeUtils.formatDateTime(getNextNDayEndTime(100)));
    	System.err.println(getDayOfNextYearDay(new Date(), DATETIME_FORMAT));
    	
    	System.err.println(DateTimeUtils.formatDate(addDays(new Date(), -1)));
	}
    
    /**
     * 当前年的开始时间，即2012-01-01 00:00:00
     *
     * @return
     */
    public static Date getCurrentYearStartTime() {
        Calendar c = Calendar.getInstance();
        Date now = null;
        try {
            c.set(Calendar.MONTH, 0);
            c.set(Calendar.DATE, 1);
            now = shortSdf.parse(shortSdf.format(c.getTime()));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 当前年的结束时间，即2012-12-31 23:59:59
     * lgh
     *
     * @return
     */
    public static Date getCurrentYearEndTime() {
        Calendar c = Calendar.getInstance();
        Date now = null;
        try {
            c.set(Calendar.MONTH, 11);
            c.set(Calendar.DATE, 31);
            now = shortSdf.parse(shortSdf.format(c.getTime()));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return now;
    }

    /**
     * 获取下一周的最后一天
     *
     * @param date
     * @return
     * @author LQY
     * @date:Mar 16, 2016 5:11:37 PM
     */
    public static Date getLastDayNextWeek(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int week = cal.get(Calendar.DAY_OF_WEEK);
        if (week > 7) {
            cal.add(Calendar.DAY_OF_MONTH, -(week - 8) + 7);
        } else {
            cal.add(Calendar.DAY_OF_MONTH, 8 - week + 7);
        }
        return cal.getTime();
    }

    /**
     * 获取本周的日期
     *
     * @return
     * @author LQY
     * @date:Mar 17, 2016 9:39:18 PM
     */
    public static List<Date> getThisWeekdays() {
        Calendar calendar = Calendar.getInstance();
        List<Date> thisWeekDate = new ArrayList<Date>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        while (calendar.get(Calendar.DAY_OF_WEEK) != FIRST_DAY) {
            calendar.add(Calendar.DATE, -1);
        }
        try {
            for (int i = 0; i < 7; i++) {
                thisWeekDate.add(dateFormat.parse(dateFormat.format(calendar.getTime())));
                calendar.add(Calendar.DATE, 1);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return thisWeekDate;
    }

    /**
     * 获取下周的日期
     *
     * @return
     * @author LQY
     * @date:Mar 18, 2016 2:22:04 PM
     */
    public static List<Date> getNextAllWeekDay() {
        Date now = new Date();
        int weekday = getWeekDay(now);
        List<Date> nextWeekDate = new ArrayList<Date>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        for (int i = 0; i < 7; i++) {
            Calendar cal = Calendar.getInstance();
            cal.add(Calendar.DAY_OF_MONTH, +(8 - weekday + i));
            String nextDate = dateFormat.format(cal.getTime());
            try {
                nextWeekDate.add(dateFormat.parse(nextDate));
            } catch (ParseException e) {
                e.printStackTrace();
            }

        }
        return nextWeekDate;
    }

    public static int getWeekDay(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int week_index = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (week_index <= 0) {
            week_index = 7;
        }
        return week_index;
    }

}
